import os
import cv2
import imutils
import argparse
import numpy as np 
import matplotlib.pyplot as plt
import tensorflow as tf 
import time
from imutils import paths
from keras.utils import np_utils
from keras.preprocessing.image import img_to_array
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder

def conv2d(X,W,b):
    return tf.nn.bias_add(tf.nn.conv2d(X,W,[1,1,1,1],padding = 'SAME'),b)

def max_pool(X,f):
    return tf.nn.max_pool(X,[1,f,f,1],[1,1,1,1],padding = 'SAME')

def lrn(X):
    return tf.nn.lrn(X,depth_radius = 4,bias = 1.0,alpha = 0.001/9.0)

def init_W(namespace,shape,wd,stddev,reuse = False):
    with tf.variable_scope(namespace,reuse = reuse):
        initializer = tf.truncated_normal_initializer(dtype = tf.float32,stddev = stddev)
        W = tf.get_variable("W",shape = shape,initializer = initializer)

        if wd:
            weight_decay = tf.multiply(tf.nn.l2_loss(W),wd,name = 'weight_loss')
            tf.add_to_collection('losses',weight_decay)
    return W

def init_b(namespace,shape,reuse = False):
    with tf.variable_scope(namespace,reuse = reuse):
        initializer = tf.constant_initializer(0.0)
        b = tf.get_variable('b',shape = shape,initializer = initializer)
    return b

def inference(images,reuse = False):

    W1 = init_W("conv1",[5,5,1,20],None,0.01,reuse)
    b1 = init_b("conv1",[20],reuse)
    conv1 = conv2d(images,W1,b1)
    conv1_act = tf.nn.relu(conv1)
    pool1 = max_pool(conv1_act,2)

    W2 = init_W("conv2",[5,5,20,50],None,0.01,reuse)
    b2 = init_b("conv2",[50],reuse)
    conv2 = conv2d(pool1,W2,b2)
    conv2_act = tf.nn.relu(conv2)
    pool2 = max_pool(conv2_act,2)

    shape = pool2.get_shape()
    wfc1 = init_W("FC1",[(shape[1].value*shape[2].value*shape[3].value),500],None,1e-2,reuse)
    bfc1 = init_b("FC1",[500],reuse)
    
    reshape = tf.reshape(pool2,[-1,shape[1].value*shape[2].value*shape[3].value])
    fc1 = tf.matmul(reshape,wfc1) + bfc1
    fc1_out = tf.nn.relu(fc1)

    wfc2 = init_W("FC2",[500,2],None,1e-2,reuse)
    bfc2 = init_b("FC2",[2],reuse)
    fc2 = tf.matmul(fc1_out,wfc2) + bfc2
    fc2_out = tf.nn.relu(fc2)

    
    return fc2_out


